﻿#include "ApplicationController.h"

#include "windows.h"
#include <iostream>

#include <boost/bind.hpp>
#include "gameplay/client/ClientController.h"
#include "gameplay/local/LocalController.h"
#include "gameplay/server/ServerController.h"
#include "../views/concrete/graphic/ApplicationView.h"

using namespace Controllers;

ApplicationController::ApplicationController(Utils::GUI::Form* form)
	: view(NULL), gameplay_controller(NULL), form(form), is_ended(false)
{
	view = new Views::Graphic::ApplicationView(form);
}

ApplicationController::~ApplicationController()
{
	delete gameplay_controller;
	gameplay_controller = NULL;
	delete view;
}

void ApplicationController::startApp()
{
	connectEvent<void (Domain::Configuration::GAME_MODE)>(view->gameModePickEvent,
		boost::bind(&ApplicationController::setController, this, _1));
	view->openGameModeDialog();
}

void ApplicationController::setController(Domain::Configuration::GAME_MODE mode)
{
	switch(mode)
	{
	case Domain::Configuration::LOCAL:
		gameplay_controller = new LocalController(form);
		break;
	case Domain::Configuration::SERVER:
		gameplay_controller = new ServerController(form);
		break;
	case Domain::Configuration::CLIENT:
		gameplay_controller = new ClientController(form);
		break;
	}
	setGameplayControllerEvents();
	startGame();
}

void ApplicationController::setGameplayControllerEvents()
{
	connectEvent<void (Players::Player*, Cards::CardSet, Domain::Configuration::GAME_END_REASON)>(
		gameplay_controller->gameLostEvent, boost::bind(&ApplicationController::gameLost, this, _1, _2, _3));
	connectEvent<void (Players::Player*, Cards::CardSet, Domain::Configuration::GAME_END_REASON)>(
		gameplay_controller->gameWonEvent, boost::bind(&ApplicationController::gameWon, this, _1, _2, _3));
}

void ApplicationController::startGame()
{
	gameplay_controller->startGame();
}

void ApplicationController::gameLost(Players::Player* player, Cards::CardSet cards, Domain::Configuration::GAME_END_REASON reason)
{
	view->gameLost(player, cards, reason);
}

void ApplicationController::gameWon(Players::Player* player, Cards::CardSet cards, Domain::Configuration::GAME_END_REASON reason)
{
	view->gameWon(player, cards, reason);
}

bool ApplicationController::isEnded()
{
	return is_ended;
}

void ApplicationController::handleException(std::exception&)
{
	MessageBoxW(0, L"Wyst�pi� nieznany b��d aplikacji i zostanie ona zamkni�ta", L"Nieznany b��d", MB_ICONERROR);
	is_ended = true;
}

void ApplicationController::handleException(Domain::Helpers::NetworkException& e)
{
	MessageBoxW(0, L"Wyst�pi� b��d z po��czeniem i aplikacja zostanie zamkni�ta.", L"B��d po��czenia", MB_ICONERROR);
	is_ended = true;
}

